 /*******************************************************************************
  * Copyright (c) 2006, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.ui.internal;

 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IPersistableEditor;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IEditorRegistry;
 import org.eclipse.ui.IElementFactory;
 import org.eclipse.ui.IMemento;
 import org.eclipse.ui.IPersistableElement;
 import org.eclipse.ui.IReusableEditor;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchPart2;
 import org.eclipse.ui.IWorkbenchPart3;
 import org.eclipse.ui.IWorkbenchPartConstants;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.internal.editorsupport.ComponentSupport;
 import org.eclipse.ui.internal.misc.StatusUtil;
 import org.eclipse.ui.internal.misc.UIStats;
 import org.eclipse.ui.internal.part.NullEditorInput;
 import org.eclipse.ui.internal.registry.EditorDescriptor;
 import org.eclipse.ui.internal.registry.EditorRegistry;
 import org.eclipse.ui.internal.tweaklets.TabBehaviour;
 import org.eclipse.ui.internal.tweaklets.Tweaklets;
 import org.eclipse.ui.internal.util.Util;
 import org.eclipse.ui.part.IWorkbenchPartOrientation;
 import org.eclipse.ui.part.MultiEditor;
 import org.eclipse.ui.part.MultiEditorInput;
 import org.eclipse.ui.statushandlers.StatusManager;

 public class EditorReference extends WorkbenchPartReference implements
         IEditorReference {

     /**
      *
      */
     private final EditorManager manager;

     private IMemento editorMemento;

     private IMemento editorState = null;

     /**
      * Flag that lets us detect malfunctioning editors that don't fire PROP_INPUT events.
      * It is never needed for a correctly-functioning
      */
     private boolean expectingInputChange = false;
     
     /**
      * Flag that determines whether we've already reported that this editor is malfunctioning.
      * This prevents us from spamming the event log if we repeatedly detect the same error in
      * a particular editor. If we ever detect an editor is violating its public contract in
      * a way we can recover from (such as a missing property change event), we report the error
      * once and then silently ignore errors from the same editor.
      */
     private boolean reportedMalfunctioningEditor = false;
     
     /**
      * User-readable name of the editor's input
      */
     String name;

     String factoryId;

     IEditorInput restoredInput;
     
     /**
      * If the reference is instantiated as a MultiEditor, we need to dispose the
      * inner references correctly.
      */
     private IEditorReference[] multiEditorChildren = null;

     
     /**
      * @param manager
      * The editor manager for this reference
      * @param input
      * our input
      * @param desc
      * the descriptor from the declaration
      */
     public EditorReference(EditorManager manager, IEditorInput input,
             EditorDescriptor desc) {
         this(manager, input, desc, null);
     }
     
     /**
      * @param manager
      * The editor manager for this reference
      * @param input
      * our input
      * @param desc
      * the descriptor from the declaration
      * @param editorState
      * propogate state from another editor. Can be <code>null</code>.
      */
     public EditorReference(EditorManager manager, IEditorInput input,
             EditorDescriptor desc, IMemento editorState) {
         this.manager = manager;
         initListenersAndHandlers();
         restoredInput = input;
         this.editorState = editorState;
         init(desc.getId(), desc.getLabel(),
                 "", desc.getImageDescriptor(), desc.getLabel(), ""); //$NON-NLS-1$//$NON-NLS-2$
 }
     
     /**
      * Constructs a new editor reference for use by editors being restored from
      * a memento.
      */
     EditorReference(EditorManager manager, IMemento memento) {
         this.manager = manager;
         initListenersAndHandlers();
         this.editorMemento = memento;
         if (EditorManager.useIPersistableEditor()) {
             editorState = editorMemento.getChild(IWorkbenchConstants.TAG_EDITOR_STATE);
         } else {
             editorState = null;
         }
         String id = memento.getString(IWorkbenchConstants.TAG_ID);
         String title = memento.getString(IWorkbenchConstants.TAG_TITLE);
         String tooltip = Util.safeString(memento
                 .getString(IWorkbenchConstants.TAG_TOOLTIP));
         String partName = memento
                 .getString(IWorkbenchConstants.TAG_PART_NAME);

         IMemento propBag = memento.getChild(IWorkbenchConstants.TAG_PROPERTIES);
         if (propBag != null) {
             IMemento[] props = propBag
                     .getChildren(IWorkbenchConstants.TAG_PROPERTY);
             for (int i = 0; i < props.length; i++) {
                 propertyCache.put(props[i].getID(), props[i].getTextData());
             }
         }

         // For compatibility set the part name to the title if not found
 if (partName == null) {
             partName = title;
         }

         // Get the editor descriptor.
 EditorDescriptor desc = null;
         if (id != null) {
             desc = getDescriptor(id);
         }
         // desc may be null if id is null or desc is not found, but findImage below handles this
 String location = memento.getString(IWorkbenchConstants.TAG_PATH);
         IPath path = location == null ? null : new Path(location);
         ImageDescriptor iDesc = this.manager.findImage(desc, path);

         this.name = memento.getString(IWorkbenchConstants.TAG_NAME);
         if (this.name == null) {
             this.name = title;
         }
         setPinned("true".equals(memento.getString(IWorkbenchConstants.TAG_PINNED))); //$NON-NLS-1$

         IMemento inputMem = memento.getChild(IWorkbenchConstants.TAG_INPUT);
         if (inputMem != null) {
             this.factoryId = inputMem
                     .getString(IWorkbenchConstants.TAG_FACTORY_ID);
         }

         init(id, title, tooltip, iDesc, partName, ""); //$NON-NLS-1$
 }

     public EditorDescriptor getDescriptor() {
         return getDescriptor(getId());
     }
     
     /**
      * @since 3.1
      *
      * @param id
      * @return
      */
     private EditorDescriptor getDescriptor(String id) {
         EditorDescriptor desc;
         IEditorRegistry reg = WorkbenchPlugin.getDefault()
                 .getEditorRegistry();
         desc = (EditorDescriptor) reg.findEditor(id);
         return desc;
     }
     
     /**
      * Initializes the necessary editor listeners and handlers
      */
     private void initListenersAndHandlers() {
         // Create a property change listener to track the "close editors automatically"
 // preference and show/remove the pin icon on editors
 // Only 1 listener will be created in the EditorManager when necessary
 this.manager.checkCreateEditorPropListener();
         // Create a keyboard shortcut handler for pinning editors
 // Only 1 handler will be created in the EditorManager when necessary
 this.manager.checkCreatePinEditorShortcutKeyHandler();
     }

     protected PartPane createPane() {
         return new EditorPane(this, this.manager.page, this.manager.editorPresentation.getActiveWorkbook());
     }
     
     /**
      * This method is called when there should be a change in the editor pin
      * status (added or removed) so that it will ask its presentable part
      * to fire a PROP_TITLE event in order for the presentation to request
      * the new icon for this editor
      */
     public void pinStatusUpdated() {
         firePropertyChange(IWorkbenchPart.PROP_TITLE);
     }
     
     public String getFactoryId() {
         IEditorPart editor = getEditor(false);
         if (editor != null) {
             IPersistableElement persistable = editor.getEditorInput()
                     .getPersistable();
             if (persistable != null) {
                 return persistable.getFactoryId();
             }
             return null;
         }
         return factoryId;
     }

     protected String computePartName() {
         if (part instanceof IWorkbenchPart2) {
             return super.computePartName();
         } else {
             return getRawTitle();
         }
     }

     public String getName() {
         if (part != null) {
             return getEditor(false).getEditorInput().getName();
         }
         return name;
     }

     public IEditorPart getEditor(boolean restore) {
         return (IEditorPart)getPart(restore);
     }

     protected void releaseReferences() {
         super.releaseReferences();
         editorMemento = null;
         editorState = null;
         name = null;
         factoryId = null;
         restoredInput = null;
     }

     void setName(String name) {
         this.name = name;
     }

     public IMemento getMemento() {
         return editorMemento;
     }

     public IWorkbenchPage getPage() {
         return this.manager.page;
     }

     protected void doDisposePart() {
         if (multiEditorChildren!=null) {
             for (int i=0; i<multiEditorChildren.length; ++i) {
                 EditorReference ref = (EditorReference)multiEditorChildren[i];
                 if (ref!=null) {
                     ref.dispose();
                 }
             }
             multiEditorChildren = null;
         }

         if (part != null) {
             EditorSite site = (EditorSite) ((IEditorPart)part).getEditorSite();
             manager.disposeEditorActionBars((EditorActionBars) site.getActionBars());
             site.dispose();
         }
         
         this.manager.checkDeleteEditorResources();

         super.doDisposePart();
         editorMemento = null;
         editorState = null;
         restoredInput = new NullEditorInput();
     }

     public IEditorInput getEditorInput() throws PartInitException {
         if (isDisposed()) {
             if (!(restoredInput instanceof NullEditorInput)) {
                 restoredInput = new NullEditorInput();
             }
             return restoredInput;
         }
         
         IEditorPart part = getEditor(false);
         if (part != null) {
             return part.getEditorInput();
         }
         return getRestoredInput();
     }
     
     private IEditorInput getRestoredInput() throws PartInitException {
         if (restoredInput != null) {
             return restoredInput;
         }
         
         // Get the input factory.
 IMemento editorMem = getMemento();
         if (editorMem == null) {
             throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_no_persisted_state, getId(), getName()));
         }
         IMemento inputMem = editorMem
                 .getChild(IWorkbenchConstants.TAG_INPUT);
         String factoryID = null;
         if (inputMem != null) {
             factoryID = inputMem
                     .getString(IWorkbenchConstants.TAG_FACTORY_ID);
         }
         if (factoryID == null) {
             throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_no_input_factory_ID, getId(), getName()));
         }
         IAdaptable input = null;
         String label = null; // debugging only
 if (UIStats.isDebugging(UIStats.CREATE_PART_INPUT)) {
             label = getName() != null ? getName() : factoryID;
         }
         try {
             UIStats.start(UIStats.CREATE_PART_INPUT, label);
             IElementFactory factory = PlatformUI.getWorkbench()
                     .getElementFactory(factoryID);
             if (factory == null) {
                 throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_bad_element_factory, new Object [] { factoryID, getId(), getName() }));
             }

             // Get the input element.
 input = factory.createElement(inputMem);
             if (input == null) {
                 throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_create_element_returned_null, new Object [] { factoryID, getId(), getName() }));
             }
         } finally {
             UIStats.end(UIStats.CREATE_PART_INPUT, input, label);
         }
         if (!(input instanceof IEditorInput)) {
             throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_wrong_createElement_result, new Object [] { factoryID, getId(), getName() }));
         }
         restoredInput = (IEditorInput) input;
         return restoredInput;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IWorkbenchPartReference#getTitleImage()
      * This method will append a pin to the icon of the editor
      * if the "automatically close editors" option in the
      * preferences is enabled and the editor has been pinned.
      */
     public ImageDescriptor computeImageDescriptor() {
         ImageDescriptor descriptor = super.computeImageDescriptor();
         if (!isPinned()) {
             return descriptor;
         }

         // Check if the pinned preference is set
 IPreferenceStore prefStore = WorkbenchPlugin.getDefault()
                 .getPreferenceStore();
         boolean bUsePin = prefStore
                 .getBoolean(IPreferenceConstants.REUSE_EDITORS_BOOLEAN)
                 || ((TabBehaviour)Tweaklets.get(TabBehaviour.KEY)).alwaysShowPinAction();

         if (!bUsePin) {
             return descriptor;
         }

         ImageDescriptor pinDesc = this.manager.getEditorPinImageDesc();
         if (pinDesc == null) {
             return descriptor;
         }

         return new OverlayIcon(descriptor, pinDesc, new Point(16, 16));
     }

     /**
      * Wrapper for restoring the editor. First, this delegates to busyRestoreEditorHelper
      * to do the real work of restoring the view. If unable to restore the editor, this
      * method tries to substitute an error part and return success.
      *
      * @param ref_
      * @param manager TODO
      * @return
      */
     protected IWorkbenchPart createPart() {
         if (EditorRegistry.EMPTY_EDITOR_ID.equals(getId())) {
             return getEmptyEditor(getDescriptor());
         }
         PartInitException exception = null;
         
         IWorkbenchPart result = null;
         
         // Try to restore the editor -- this does the real work of restoring the editor
 //
 try {
             result = createPartHelper();
         } catch (PartInitException e) {
             exception = e;
         }

         
         // If unable to create the part, create an error part instead
 // and pass the error to the status handling facility
 if (exception != null) {
             
             IStatus originalStatus = exception.getStatus();
             IStatus logStatus = StatusUtil.newStatus(originalStatus,
                     NLS.bind("Unable to create editor ID {0}: {1}", //$NON-NLS-1$
 getId(), originalStatus.getMessage()));
             IStatus displayStatus = StatusUtil.newStatus(originalStatus,
                     WorkbenchMessages.EditorManager_unableToCreateEditor);

             // Pass the error to the status handling facility
 StatusManager.getManager().handle(logStatus);
             StatusManager.getManager().handle(displayStatus,
                         StatusManager.SHOW);
             
             ErrorEditorPart part = new ErrorEditorPart(displayStatus);
             
             IEditorInput input;
             try {
                 input = getEditorInput();
             } catch (PartInitException e1) {
                 input = new NullEditorInput();
             }
             
             EditorPane pane = (EditorPane)getPane();
             
             pane.createControl((Composite) manager.page.getEditorPresentation().getLayoutPart().getControl());
             
             EditorDescriptor descr = getDescriptor();
             
             EditorSite site = new EditorSite(this, part, manager.page, descr);
             
             site.setActionBars(new EditorActionBars(manager.page, site.getWorkbenchWindow(), getId()));
             
             part.init(site, input);

             Composite parent = (Composite)pane.getControl();
             Composite content = new Composite(parent, SWT.NONE);
             content.setLayout(new FillLayout());
             
             try {
                 part.createPartControl(content);
             } catch (Exception e) {
                 content.dispose();
                 StatusUtil.handleStatus(e, StatusManager.SHOW
                         | StatusManager.LOG);
                 return null;
             }

             result = part;
         }
         
         return result;
     }
     
     protected void partPropertyChanged(Object source, int propId) {
         
         // Detect badly behaved editors that don't fire PROP_INPUT events
 // when they're supposed to. This branch is only needed to handle
 // malfunctioning editors.
 if (propId == IWorkbenchPartConstants.PROP_INPUT) {
             expectingInputChange = false;
         }
         
         super.partPropertyChanged(source, propId);
     }
     
     /**
      * Attempts to set the input of the editor to the given input. Note that the input
      * can't always be changed for an editor. Editors that don't implement IReusableEditor
      * can't have their input changed once they've been materialized.
      *
      * @since 3.1
      *
      * @param input new input
      * @return true iff the input was actually changed
      */
     public boolean setInput(IEditorInput input) {

         if (part != null) {
             if (part instanceof IReusableEditor) {
                 IReusableEditor editor = (IReusableEditor) part;
        
                 expectingInputChange = true;
                 
                 editor.setInput(input);
                 
                 // If the editor never fired a PROP_INPUT event, log the fact that we've discovered
 // a buggy editor and fire the event for free. Firing the event for free isn't required
 // and cannot be relied on (it only works if the input change was triggered by this
 // method, and there are definitely other cases where events will still be lost),
 // but older versions of the workbench did this so we fire it here in the spirit
 // of playing nice.
 if (expectingInputChange) {

                     // Log the fact that this editor is broken
 reportMalfunction("Editor is not firing a PROP_INPUT event in response to IReusableEditor.setInput(...)"); //$NON-NLS-1$

                     // Fire the property for free (can't be relied on since there are other ways the input
 // can change, but we do it here to be consistent with older versions of the workbench)
 firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);
                 }
                 
                 return editor.getEditorInput() == input;

             } else {
                 // Can't change the input if the editor already exists and isn't an IReusableEditor
 return false;
             }
         } else {
             // Changing the input is trivial and always succeeds if the editor doesn't exist yet
 if (input != restoredInput) {
                 restoredInput = input;
                 
                 firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);
             }
         }
         
         return true;
     }

     /**
      * Reports a recoverable malfunction in the system log. A recoverable malfunction would be
      * something like failure to fire an expected property change. Only the first malfunction is
      * recorded to avoid spamming the system log with repeated failures in the same editor.
      *
      * @since 3.1
      *
      * @param string
      */
     private void reportMalfunction(String string) {
         if (!reportedMalfunctioningEditor) {
             reportedMalfunctioningEditor = true;

             String errorMessage = "Problem detected with part " + getId(); //$NON-NLS-1$
 if (part != null) {
                 errorMessage += " (class = " + part.getClass().getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 }

             errorMessage += ": " + string; //$NON-NLS-1$

             StatusManager.getManager().handle(
                     StatusUtil.newStatus(getDescriptor().getPluginId(),
                             errorMessage, null));
         }
     }

     private IEditorPart createPartHelper() throws PartInitException {
         
         // Things that will need to be disposed if an exception occurs (listed
 // in the order they
 // need to be disposed, and set to null if they haven't been created yet)
 Composite content = null;
         IEditorPart part = null;
         EditorActionBars actionBars = null;
         EditorSite site = null;
         
         try {
             IEditorInput editorInput = getEditorInput();
             
             // Get the editor descriptor.
 String editorID = getId();
             EditorDescriptor desc = getDescriptor();
             
             if (desc == null) {
                 throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_missing_editor_descriptor, editorID));
             }
             
             
             if (desc.isInternal()) {
                 // Create an editor instance.
 try {
                     UIStats.start(UIStats.CREATE_PART, editorID);
                     part = manager.createPart(desc);
                     
                     if (part != null && part instanceof MultiEditor) {
                         multiEditorChildren = manager.openMultiEditor(this,
                             (MultiEditor) part, (MultiEditorInput) editorInput);
                     }
                     if (part instanceof IWorkbenchPart3) {
                         createPartProperties((IWorkbenchPart3)part);
                     }
                 } finally {
                     UIStats.end(UIStats.CREATE_PART, this, editorID);
                 }
                 
             } else if (desc.getId().equals(
                     IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID)) {
                 
                 part = ComponentSupport.getSystemInPlaceEditor();
                 
                 if (part == null) {
                     throw new PartInitException(WorkbenchMessages.EditorManager_no_in_place_support);
                 }
             } else {
                 throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_invalid_editor_descriptor, editorID));
             }
             // Create a pane for this part
 PartPane pane = getPane();
     
             pane.createControl((Composite) manager.page.getEditorPresentation().getLayoutPart().getControl());
             
             // Create controls
 int style = SWT.NONE;
             if(part instanceof IWorkbenchPartOrientation){
                 style = ((IWorkbenchPartOrientation) part).getOrientation();
             }
     
             // Link everything up to the part reference (the part reference itself should not have
 // been modified until this point)
 site = manager.createSite(this, part, desc, editorInput);
             
             // if there is saved state that's appropriate, pass it on
 if (part instanceof IPersistableEditor && editorState != null) {
                 ((IPersistableEditor) part).restoreState(editorState);
             }
             
             // Remember the site and the action bars (now that we've created them, we'll need to dispose
 // them if an exception occurs)
 actionBars = (EditorActionBars) site.getActionBars();
             
             Composite parent = (Composite)pane.getControl();
             content = new Composite(parent, style);
     
             content.setLayout(new FillLayout());
     
             try {
                 UIStats.start(UIStats.CREATE_PART_CONTROL, editorID);
                 part.createPartControl(content);
             
                 parent.layout(true);
             } finally {
                 UIStats.end(UIStats.CREATE_PART_CONTROL, part, editorID);
             }
     
             // The editor should now be fully created. Exercise its public interface, and sanity-check
 // it wherever possible. If it's going to throw exceptions or behave badly, it's much better
 // that it does so now while we can still cancel creation of the part.
 PartTester.testEditor(part);
             
             return part;
             
         } catch (Exception e) {
             // Dispose anything which we allocated in the try block
 if (content != null) {
                 try {
                     content.dispose();
                 } catch (RuntimeException re) {
                     StatusManager.getManager().handle(
                             StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
                                     re));
                 }
             }
     
             if (part != null) {
                 try {
                     part.dispose();
                 } catch (RuntimeException re) {
                     StatusManager.getManager().handle(
                             StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
                                     re));
                 }
             }
             
             if (actionBars != null) {
                 try {
                     manager.disposeEditorActionBars(actionBars);
                 } catch (RuntimeException re) {
                     StatusManager.getManager().handle(
                             StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
                                     re));
                 }
             }
             
             if (site != null) {
                 try {
                     site.dispose();
                 } catch (RuntimeException re) {
                     StatusManager.getManager().handle(
                             StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
                                     re));
                 }
             }
             
             throw new PartInitException(StatusUtil.getLocalizedMessage(e), StatusUtil.getCause(e));
         }
     
     }
     
     /**
      * A quick way of finding out if this reference points to a MultiEditor.
      * It depends on the fact that a MultiEditor does not lazily
      * instantiate it's child editors.
      *
      * @return true if it has inner editor reference or the input is
      * MultiEditorInput.
      */
     public boolean isMultiReference() {
         return multiEditorChildren!=null || restoredInput instanceof MultiEditorInput;
     }

     /**
      * @param b
      * @return
      */
     public IEditorPart getEmptyEditor(EditorDescriptor descr) {
         ErrorEditorPart part = new ErrorEditorPart();
         
         IEditorInput input;
         try {
             input = getEditorInput();
         } catch (PartInitException e1) {
             input = new NullEditorInput();
         }
         
         EditorPane pane = (EditorPane)getPane();
         
         pane.createControl((Composite) manager.page.getEditorPresentation().getLayoutPart().getControl());
         
         EditorSite site = new EditorSite(this, part, manager.page, descr);
         
         site.setActionBars(new EditorActionBars(manager.page, site.getWorkbenchWindow(), getId()));

         part.init(site, input);

         Composite parent = (Composite)pane.getControl();
         Composite content = new Composite(parent, SWT.NONE);
         content.setLayout(new FillLayout());
         
         try {
             part.createPartControl(content);
         } catch (Exception e) {
             content.dispose();
             StatusManager.getManager().handle(
                     StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
             return null;
         }

         this.part = part;
         // Add a dispose listener to the part. This dispose listener does nothing but log an exception
 // if the part's widgets get disposed unexpectedly. The workbench part reference is the only
 // object that should dispose this control, and it will remove the listener before it does so.

         part.setPartName("(Empty)"); //$NON-NLS-1$
 refreshFromPart();
         releaseReferences();
         
         if (((WorkbenchPage)getPage()).getActiveEditorReference()!=this) {
             fireInternalPropertyChange(INTERNAL_PROPERTY_OPENED);
         }
         
         return part;
     }
 }


